/**
 * This class contains unit tests for validating the behavior of Apex classes
 * and triggers.
 *
 * Unit tests are class methods that verify whether a particular piece
 * of code is working properly. Unit test methods take no arguments,
 * commit no data to the database, and are flagged with the testMethod
 * keyword in the method definition.
 *
 * All test methods in an organization are executed whenever Apex code is deployed
 * to a production organization to confirm correctness, ensure code
 * coverage, and prevent regressions. All Apex classes are
 * required to have at least 75% code coverage in order to be deployed
 * to a production organization. In addition, all triggers must have some code coverage.
 * 
 * The @isTest class annotation indicates this class only contains test
 * methods. Classes defined with the @isTest annotation do not count against
 * the organization size limit for all Apex scripts.
 *
 * See the Apex Language Reference for more information about Testing and Code Coverage.
 */
@isTest
private class SOLOFinanceActionsExtTest {

	private static SOLOFinanceActionsExt extension;
	private static User testUser;
	private static User usr_analyst;
	private static User usr_admin;
	private static User usr_acct;
	private static Account acct;
	private static Opportunity opp;
	private static Map<Id, RecordType> oorOppRts;
	private static Map<Id, RecordType> oorAccntRts;
	private static Map<string, RecordType> oorRtByNameMap;
	private static string oppName;
	
    static testMethod void myAnalystApproveTest() 
	{
        // added by plo, get record types for opps and accounts
        oorOppRts = new Map<Id,RecordType>(
           [SELECT Id, Name, DeveloperName, sobjectType FROM RecordType 
            WHERE DeveloperName IN ('SFA_OOR_Order','SFA_OOR_Renwals') AND sObjectType = 'Opportunity']);
        oorAccntRts = new Map<Id,RecordType>(
           [SELECT Id, Name, DeveloperName, sobjectType FROM RecordType 
            WHERE DeveloperName IN ('Local_Advertiser') AND sObjectType = 'Account']);    
        
        //The reason for using separate hash maps is there are duplicate record type names in Account and Opportunity. 
        oorRtByNameMap = new Map<String,RecordType>();
        for(RecordType rt : oorOppRts.values())
        {
           oorRtByNameMap.put(rt.sObjectType + '_' + rt.DeveloperName, rt);
        }
        
        for(RecordType rt : oorAccntRts.values())
        {
           oorRtByNameMap.put(rt.sObjectType + '_' + rt.DeveloperName, rt);
        }
        
        // added by plo
        User u = [SELECT Id FROM User WHERE Id =: UserInfo.getUserId()];
        // run as sys admin when creating users to avoid mix op exceptions
        system.runas(u)
        {
	        InitializeUsers();
        }
	
        //1. Create test opportunity
        //2. Create a standard controller -- set opportunity = standard controller
        //3. Create an instance of the Extension class - extensions="SOLOFinanceActionsExt"
        //4. System.runAs(User object){ enter code in here for user}
        
        oppName = 'Test Analyst Approve Functionality';          
        CreateOpportunity(oppName);
       
    	ApexPages.Standardcontroller std = new ApexPages.Standardcontroller(opp);
    	extension = new SOLOFinanceActionsExt(std);
        
        testUser = [select FirstName from User where Id = :usr_analyst.Id limit 1];
        
        // added by plo, accept first
        opp.OwnerId = testUser.Id;
        update opp;
        /*PageReference pageRef = Page.SOLOFinanceActions;
        Test.setCurrentPage(pageRef);
        apexPages.currentPage().getParameters().put('Id',opp.Id);
        apexPages.currentPage().getParameters().put('Action','accept');
        apexPages.currentPage().getParameters().put('UserId',testUser.Id);        	
        extension.processFinanceAction();*/
        
        System.runAs(testUser)
        {
        	//parent.location.href= "/apex/SOLOFinanceActions?Id={!Opportunity.Id}&Action=save&ATTUID={!$User.ATTUID__c}&loc={!$User.SFA_Office__c}";        	
        	apexPages.currentPage().getParameters().put('Id',opp.Id);
        	apexPages.currentPage().getParameters().put('Action','save');
        	apexPages.currentPage().getParameters().put('ATTUID',usr_admin.ATTUID__c);
        	apexPages.currentPage().getParameters().put('loc',usr_admin.SFA_Office__c);
         	extension.processFinanceAction();
         	
        	apexPages.currentPage().getParameters().put('Id',opp.Id);
        	apexPages.currentPage().getParameters().put('Action','approve');
        	apexPages.currentPage().getParameters().put('ATTUID',usr_admin.ATTUID__c);
        	apexPages.currentPage().getParameters().put('loc',usr_admin.SFA_Office__c);
         	extension.processFinanceAction();
         
         // already approved, owner is the sales already, so current user can't touch it, need to create separate
         // test cases for this
         /*	
        	apexPages.currentPage().getParameters().put('Id',opp.Id);
        	apexPages.currentPage().getParameters().put('Action','deny');
        	apexPages.currentPage().getParameters().put('ATTUID',usr_admin.ATTUID__c);
        	apexPages.currentPage().getParameters().put('loc',usr_admin.SFA_Office__c);
         	extension.processFinanceAction();
         	*/
        }
    }
    
    static testMethod void myAnalystDenyTest() 
    {
        // added by plo, get record types for opps and accounts
        oorOppRts = new Map<Id,RecordType>(
           [SELECT Id, Name, DeveloperName, sobjectType FROM RecordType 
            WHERE DeveloperName IN ('SFA_OOR_Order','SFA_OOR_Renwals') AND sObjectType = 'Opportunity']);
        oorAccntRts = new Map<Id,RecordType>(
           [SELECT Id, Name, DeveloperName, sobjectType FROM RecordType 
            WHERE DeveloperName IN ('Local_Advertiser') AND sObjectType = 'Account']);    
        
        oorRtByNameMap = new Map<String,RecordType>();
        for(RecordType rt : oorOppRts.values())
        {
           oorRtByNameMap.put(rt.sObjectType + '_' + rt.DeveloperName, rt);
        }
        
        for(RecordType rt : oorAccntRts.values())
        {
           oorRtByNameMap.put(rt.sObjectType + '_' + rt.DeveloperName, rt);
        }
        
        // added by plo
        User u = [SELECT Id FROM User WHERE Id =: UserInfo.getUserId()];
        // run as sys admin when creating users to avoid mix op exceptions
        system.runas(u)
        {
	        InitializeUsers();
        }
        
        oppName = 'Test Analyst Deny Functionality';
        CreateOpportunity(oppName);
       
    	ApexPages.Standardcontroller std = new ApexPages.Standardcontroller(opp);
    	extension = new SOLOFinanceActionsExt(std);
        
        testUser = [select FirstName from User where Id = :usr_analyst.Id limit 1];
        
        // added by plo, accept first
        opp.OwnerId = testUser.Id;
        update opp;
        /*PageReference pageRef = Page.SOLOFinanceActions;
        Test.setCurrentPage(pageRef);
        apexPages.currentPage().getParameters().put('Id',opp.Id);
        apexPages.currentPage().getParameters().put('Action','accept');
        apexPages.currentPage().getParameters().put('UserId',testUser.Id);        	
        extension.processFinanceAction();*/

        System.runAs(testUser)
        {
        	apexPages.currentPage().getParameters().put('Id',opp.Id);
        	apexPages.currentPage().getParameters().put('Action','save');
        	apexPages.currentPage().getParameters().put('ATTUID',usr_admin.ATTUID__c);
        	apexPages.currentPage().getParameters().put('loc',usr_admin.SFA_Office__c);
         	extension.processFinanceAction();
         	
	
        	apexPages.currentPage().getParameters().put('Id',opp.Id);
        	apexPages.currentPage().getParameters().put('Action','deny');
        	apexPages.currentPage().getParameters().put('ATTUID',usr_admin.ATTUID__c);
        	apexPages.currentPage().getParameters().put('loc',usr_admin.SFA_Office__c);
         	extension.processFinanceAction();

        }
    }
    	
    static testMethod void myAdminApproveTest() 
    {
        // added by plo, get record types for opps and accounts
        oorOppRts = new Map<Id,RecordType>(
           [SELECT Id, Name, DeveloperName, sobjectType FROM RecordType 
            WHERE DeveloperName IN ('SFA_OOR_Order','SFA_OOR_Renwals') AND sObjectType = 'Opportunity']);
        oorAccntRts = new Map<Id,RecordType>(
           [SELECT Id, Name, DeveloperName, sobjectType FROM RecordType 
            WHERE DeveloperName IN ('Local_Advertiser') AND sObjectType = 'Account']);    
        
        oorRtByNameMap = new Map<String,RecordType>();
        for(RecordType rt : oorOppRts.values())
        {
           oorRtByNameMap.put(rt.sObjectType + '_' + rt.DeveloperName, rt);
        }
        
        for(RecordType rt : oorAccntRts.values())
        {
           oorRtByNameMap.put(rt.sObjectType + '_' + rt.DeveloperName, rt);
        }

        // added by plo
        User u = [SELECT Id FROM User WHERE Id =: UserInfo.getUserId()];
        // run as sys admin when creating users to avoid mix op exceptions
        system.runas(u)
        {
	        InitializeUsers();
        }
     
        oppName = 'Test Admin Approve Functionality';
        CreateOpportunity(oppName);
        
        opp.OwnerId = usr_admin.Id;
        update opp;
       
    	ApexPages.Standardcontroller std = new ApexPages.Standardcontroller(opp);
    	extension = new SOLOFinanceActionsExt(std);
        
        testUser = [select FirstName from User where Id = :usr_admin.Id limit 1];
          	
		System.runAs(testUser)
		{
			apexPages.currentPage().getParameters().put('Id',opp.Id);
        	apexPages.currentPage().getParameters().put('Action','save');
        	apexPages.currentPage().getParameters().put('ATTUID',usr_admin.ATTUID__c);
        	apexPages.currentPage().getParameters().put('loc',usr_admin.SFA_Office__c);
         	extension.processFinanceAction();
         	
        	apexPages.currentPage().getParameters().put('Id',opp.Id);
        	apexPages.currentPage().getParameters().put('Action','approve');
        	apexPages.currentPage().getParameters().put('ATTUID',usr_admin.ATTUID__c);
        	apexPages.currentPage().getParameters().put('loc',usr_admin.SFA_Office__c);
         	extension.processFinanceAction();
		}
    }
        
    static testMethod void myAdminDenyTest() 
    {
		// added by plo, get record types for opps and accounts
        oorOppRts = new Map<Id,RecordType>(
           [SELECT Id, Name, DeveloperName, sobjectType FROM RecordType 
            WHERE DeveloperName IN ('SFA_OOR_Order','SFA_OOR_Renwals') AND sObjectType = 'Opportunity']);
        oorAccntRts = new Map<Id,RecordType>(
           [SELECT Id, Name, DeveloperName, sobjectType FROM RecordType 
            WHERE DeveloperName IN ('Local_Advertiser') AND sObjectType = 'Account']);    
        
        oorRtByNameMap = new Map<String,RecordType>();
        for(RecordType rt : oorOppRts.values())
        {
           oorRtByNameMap.put(rt.sObjectType + '_' + rt.DeveloperName, rt);
        }
        
        for(RecordType rt : oorAccntRts.values())
        {
           oorRtByNameMap.put(rt.sObjectType + '_' + rt.DeveloperName, rt);
        }
        
        // added by plo
        User u = [SELECT Id FROM User WHERE Id =: UserInfo.getUserId()];
        // run as sys admin when creating users to avoid mix op exceptions
        system.runas(u)
        {
	        InitializeUsers();
        }
       
        oppName = 'Test Admin Deny Functionality';
        CreateOpportunity(oppName);
        
        opp.OwnerId = usr_admin.Id;
        update opp;

    	ApexPages.Standardcontroller std = new ApexPages.Standardcontroller(opp);
    	extension = new SOLOFinanceActionsExt(std);

        testUser = [select FirstName from User where Id = :usr_admin.Id limit 1];
    	
    	System.runAs(testUser)
		{
			apexPages.currentPage().getParameters().put('Id',opp.Id);
        	apexPages.currentPage().getParameters().put('Action','save');
        	apexPages.currentPage().getParameters().put('ATTUID',usr_admin.ATTUID__c);
        	apexPages.currentPage().getParameters().put('loc',usr_admin.SFA_Office__c);
         	extension.processFinanceAction();
         	
        	apexPages.currentPage().getParameters().put('Id',opp.Id);
        	apexPages.currentPage().getParameters().put('Action','deny');
        	apexPages.currentPage().getParameters().put('ATTUID',usr_admin.ATTUID__c);
        	apexPages.currentPage().getParameters().put('loc',usr_admin.SFA_Office__c);
         	extension.processFinanceAction();
		}
    }

    
    private static void InitializeUsers()
    {
	    usr_admin = new User();
	    usr_admin.UserName = 'testfinanceadmin@atti.com';
	    usr_admin.LastName = 'Test Finance Administrator';
	    usr_admin.Email = 'testfinanceadmin@atti.com';
	    usr_admin.ATTUID__c = 'abc123';
	    usr_admin.AFrontier_Employee_ID__c='IYP2671';
	    usr_admin.SFA_Office__c='PAS';
	    usr_admin.ATTi_UID__c = 'abc';
	    usr_admin.Alias = 'admin';
	    usr_admin.TimeZoneSidKey = 'America/Los_Angeles';
    	usr_admin.LocaleSidKey = 'en_US';
    	usr_admin.EmailEncodingKey = 'UTF-8';
    	usr_admin.LanguageLocaleKey = 'en_US';
	    usr_admin.ProfileId = [select ID from Profile where Name =: 'SFA OOR Finance Analysts' limit 1].Id;
	    usr_admin.UserRoleId = [select ID from UserRole where Name =: 'SFA Finance Admin' limit 1].Id;
	    insert usr_admin;
	    
	    usr_analyst = new User();
	    usr_analyst.UserName = 'testfinanceanalyst@atti.com';
	    usr_analyst.LastName = 'Test Finance Analyst';
	    usr_analyst.Email = 'testfinanceanalyst@atti.com';
	    usr_analyst.ATTUID__c = 'def456';
	    usr_analyst.AFrontier_Employee_ID__c='IYP3120';
	    usr_analyst.SFA_Office__c='PAS';
	    usr_analyst.ATTi_UID__c = 'def';
	    usr_analyst.Alias = 'anlst';
	    usr_analyst.TimeZoneSidKey = 'America/Los_Angeles';
    	usr_analyst.LocaleSidKey = 'en_US';
    	usr_analyst.EmailEncodingKey = 'UTF-8';
    	usr_analyst.LanguageLocaleKey = 'en_US';
	    usr_analyst.ProfileId = [select ID from Profile where Name =: 'SFA OOR Finance Analysts' limit 1].Id;
	    usr_analyst.UserRoleId = [select ID from UserRole where Name =: 'SFA Finance Analyst' limit 1].Id;
	    insert usr_analyst;
	    
	    usr_acct = new User();
	    usr_acct.UserName = 'gbramhall@1234.com';
	    usr_acct.LastName = 'Test Account Owner';
	    usr_acct.Email = 'gbramhall_xxx@atti.com';
	    usr_acct.ATTUID__c = 'ghi789';
	    usr_acct.AFrontier_Employee_ID__c='10528P20';
	    usr_acct.SFA_Office__c='LVN';
	    usr_acct.ATTi_UID__c = 'ghi';
	    usr_acct.Alias = 'gbram';
	    usr_acct.TimeZoneSidKey = 'America/Los_Angeles';
    	usr_acct.LocaleSidKey = 'en_US';
    	usr_acct.EmailEncodingKey = 'UTF-8';
    	usr_acct.LanguageLocaleKey = 'en_US';
	    usr_acct.ProfileId = [select ID from Profile where Name =: 'SFA OOR Media Consultants' limit 1].Id;
	    usr_acct.UserRoleId = [select ID from UserRole where Name =: 'OOR Las Vegas (LVN) MC2' limit 1].Id;
	    insert usr_acct;
    }
	    
    private static void CreateOpportunity(string opportunityName)
    {
	  // added by plo, initialize test data
	  opp = new Opportunity();       
      acct = new Account(OwnerId= usr_acct.Id); 
	  acct.Name = 'Test OOR Account';
	  acct.RecordTypeId = oorRtByNameMap.get('Account_Local_Advertiser').Id;
	  insert acct;
	  
	  opp.OwnerId = usr_admin.Id;
	  opp.Name = opportunityName;
	  opp.CloseDate = Date.today(); 
	  opp.SOLO_Order_State__c = 'F';       
      opp.StageName = 'Open'; 
      opp.RecordTypeId = oorRtByNameMap.get('Opportunity_SFA_OOR_Renwals').Id;
      opp.AccountId = acct.Id;
      opp.Account = acct;
      opp.Account.OwnerId = acct.OwnerId;
	  insert opp;
    }
}